#include "signalLamp.h"

//初始化两盏灯 第一盏灯有资源 第二盏灯无资源
PLAMP * lampInit(void)
{
    PLAMP *lamptmp=malloc(sizeof(PLAMP));
    //通过把两个参数进行混合得到一个独一无二的key
    key_t key = ftok("/home",1009);
    ////////////////////////共享内存的初始化///////////////////////////    
    //创建一块共享内存，权限位所有人可以读和写
    int shmID= shmget(key,MES_BUF_SIZE,IPC_CREAT|0666);
    //at共享内存，让共享内存映射到当前进程
    //pMem就是共享内存的地址，通过该指针就可以操作共享内存
    lamptmp->DM = shmat(shmID,NULL,0);
    ////////////////////////信号灯的初始化///////////////////////////
    //创建两盏信号灯
    lamptmp->SEMID= semget(key,2,IPC_CREAT|0666);
    //上一行代码创建了两盏灯，接下来初始化这两盏灯的值，第一盏灯有资源，第二盏灯没有资源
    semctl(lamptmp->SEMID,0,SETVAL,1);
    semctl(lamptmp->SEMID,1,SETVAL,0);
    return lamptmp;
}

//灯操作拷贝 n=1 mubiao->pMem n=0 pMem->mubiao
void cpy(int semID,void *pMem,char *mubiao,int n) 
{
    if(n==1)//把读取的数据放入共享内存中，并打开第二盏灯
    {
        struct sembuf semBuf1;
        semBuf1.sem_num = 0;//集合里面的第一盏灯
        semBuf1.sem_op = -1;//把第一盏灯的资源-1
        semBuf1.sem_flg = 0;//等待指定的灯有资源了再往下走
        //对灯集合进行操作，具体是第几盏灯写在了上面的结构体中
        //最后的参数1代表结构体的地址中只操作一盏灯
        //该函数有两重含义，1.等待指定灯的资源，2.改变资源
        semop(semID,&semBuf1,1);
        memcpy(pMem,mubiao,sizeof(BUF));
        semBuf1.sem_num = 1;//集合里面的第二盏灯
        semBuf1.sem_op = 1;//把第二盏灯的资源+1
        semop(semID,&semBuf1,1);
    }
    else if(n==0)//读取共享内存中的内容
    {
        struct sembuf semBuf1;
        semBuf1.sem_num = 1;//集合里面的第二盏灯
        semBuf1.sem_op = -1;//把第二盏灯的资源-1
        semBuf1.sem_flg = 0;//等待指定的灯有资源了再往下走
        //对灯集合进行操作，具体是第几盏灯写在了上面的结构体中
        //最后的参数1代表结构体的地址中只操作一盏灯
        //该函数有两重含义，1.等待指定灯的资源，2.改变资源
        semop(semID,&semBuf1,1);
        memcpy(mubiao,pMem,sizeof(BUF));
        semBuf1.sem_num = 0;//集合里面的第一盏灯
        semBuf1.sem_op = 1;//把第一盏灯的资源+1
        //执行结构体
        semop(semID,&semBuf1,1);
    }
}